package scrum.client.sprint;

import ilarkesto.core.scope.Scope;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import scrum.client.admin.Auth;
import scrum.client.admin.User;
import scrum.client.impediments.Impediment;
import scrum.client.project.Project;
import scrum.client.project.Requirement;

public class SprintGroupFiltered extends Sprint {

	protected Sprint wrapped;

	public SprintGroupFiltered(Map data) {
		super(data);
	}

	public SprintGroupFiltered(Project project, String label) {
		super(project, label);
	}

	public SprintGroupFiltered(Sprint sprint) {
		super(sprint.getProject(), sprint.getLabel());

		wrapped = sprint;
	}

	public List<Requirement> getRequirementsFiltered(List<Requirement> reqs) {
		return getDao().filterRequirements(Scope.get().getComponent(Auth.class).getUser(), getProject(), reqs);
	}

	@Override
	public List<Requirement> getCompletedUnclosedRequirements() {
		List<Requirement> ret = new ArrayList<Requirement>();
		for (Requirement req : getRequirementsFiltered(getRequirements())) {
			if (req.isTasksClosed() && !req.isClosed() && !req.isRejected()) ret.add(req);
		}
		return ret;
	}

	@Override
	public List<Requirement> getIncompletedRequirements() {
		List<Requirement> ret = new ArrayList<Requirement>();
		for (Requirement req : getRequirementsFiltered(getRequirements())) {
			if (!req.isTasksClosed()) ret.add(req);
		}
		return ret;
	}

	@Override
	public List<Task> getTasksBlockedBy(Impediment impediment) {
		List<Task> ret = new ArrayList<Task>();
		for (Requirement requirement : getRequirementsFiltered(getRequirements())) {
			ret.addAll(requirement.getTasksBlockedBy(impediment));
		}
		return ret;
	}

	@Override
	public float getEstimatedRequirementWork() {
		float sum = 0;
		for (Requirement requirement : getRequirementsFiltered(getRequirements())) {
			Float work = requirement.getEstimatedWork();
			if (work != null) sum += work;
		}
		return sum;
	}

	@Override
	public float getCompletedRequirementWork() {
		float sum = 0;
		for (Requirement requirement : getRequirementsFiltered(getRequirements())) {
			if (!requirement.isClosed()) continue;
			Float work = requirement.getEstimatedWork();
			if (work != null) sum += work;
		}
		return sum;
	}

	@Override
	public List<Requirement> getDecidableUndecidedRequirements() {
		List<Requirement> ret = new ArrayList<Requirement>();
		for (Requirement requirement : getRequirementsFiltered(getRequirements())) {
			if (requirement.isDecidable() && !requirement.isClosed()) ret.add(requirement);
		}
		return ret;
	}

	@Override
	public List<Task> getUnclaimedTasks(boolean sorted) {
		List<Task> ret = new ArrayList<Task>();
		List<Requirement> requirements = getRequirementsFiltered(getRequirements());
		if (sorted) Collections.sort(requirements, getRequirementsOrderComparator());
		for (Requirement requirement : requirements) {
			ret.addAll(requirement.getUnclaimedTasks());
		}
		return ret;
	}

	@Override
	public List<Task> getTasks(User user) {
		List<Task> ret = new ArrayList<Task>();
		for (Requirement requirement : getRequirementsFiltered(getRequirements())) {
			for (Task task : requirement.getTasksInSprint()) {
				if (user == null) {
					if (!task.isOwnerSet()) {
						ret.add(task);
					}
				} else {
					if (task.isOwner(user)) {
						ret.add(task);
					}
				}
			}
		}
		return ret;
	}

	@Override
	public List<Task> getClaimedTasks(User user) {
		List<Task> ret = new ArrayList<Task>();
		for (Requirement requirement : getRequirementsFiltered(getRequirements())) {
			ret.addAll(requirement.getClaimedTasks(user));
		}
		return ret;
	}

	@Override
	public int getBurnedWorkInClosedTasks() {
		int sum = 0;
		for (Requirement requirement : getRequirementsFiltered(getRequirements())) {
			sum += requirement.getBurnedWorkInClosedTasks();
		}
		return sum;
	}

	@Override
	public int getBurnedWork() {
		return Requirement.sumBurnedWork(getRequirementsFiltered(getRequirements()));
	}

	@Override
	public int getBurnedWorkInClaimedTasks() {
		int sum = 0;
		for (Requirement requirement : getRequirementsFiltered(getRequirements())) {
			sum += requirement.getBurnedWorkInClaimedTasks();
		}
		return sum;
	}

	@Override
	public int getRemainingWorkInClaimedTasks() {
		int sum = 0;
		for (Requirement requirement : getRequirementsFiltered(getRequirements())) {
			sum += requirement.getRemainingWorkInClaimedTasks();
		}
		return sum;
	}

	@Override
	public int getRemainingWorkInUnclaimedTasks() {
		int sum = 0;
		for (Requirement requirement : getRequirementsFiltered(getRequirements())) {
			sum += requirement.getRemainingWorkInUnclaimedTasks();
		}
		return sum;
	}

	@Override
	public int getRemainingWork() {
		int sum = 0;
		for (Requirement requirement : getRequirementsFiltered(getRequirements())) {
			sum += requirement.getRemainingWork();
		}
		return sum;
	}

}
